const aesfn = require('./aesfn');
const config = require('../config');
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', config.adminKey);
const hmacCrypto = function(str,key){
    const hmac=crypto.createHmac('sha256', key);
    hmac.update(str);
    return hmac.digest('hex');
}

const getTime = function(date){
    return date.getFullYear()+'/'+(date.getMonth()+1)+'/'+date.getDate()+' '+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds();
}

const mongo = require('mongodb');
const MongoClient = mongo.MongoClient;
const DB_CONN_STR = config.dbUrl;
const articleOperate = {
    addArticle: function(data) {
        let newArticle={};
        newArticle.title=data.title;
        newArticle.tags=data.tags.split(',');
        newArticle.markdown=data.markdown;
        newArticle.html=data.html;
        newArticle.publishTime = new Date();
        newArticle.readingAmount = 0;
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.articlesTable, function(err, collection) {
                    collection.insert(newArticle, function(err, docs) {
                        db.close();
                        if (!err) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    adddraft: function(data) {
        let newDraft={};
        newDraft.title=data.title;
        newDraft.tags=data.tags.split(',');
        newDraft.markdown=data.markdown;
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.draftsTable, function(err, collection) {
                    collection.insert(newDraft, function(err, docs) {
                        db.close();
                        if (!err) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    deleteArticle: function(id) {
        //id is a string just like '42314gh243214hb4'   
        const promise = new Promise(function(resolve, reject) {
            const decryptedId = aesfn.aesDecrypt(id);
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.articlesTable, function(err, collection) {
                    collection.remove({ _id: mongo.ObjectId(decryptedId) }, function(err, docs) {
                        if (!err) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                        db.close();
                    });
                });
            });
        });
        return promise;
    },

    deleteDraft: function(id) {
        //id is a string just like '42314gh243214hb4'   
        const promise = new Promise(function(resolve, reject) {
            const decryptedId = aesfn.aesDecrypt(id);
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.draftsTable, function(err, collection) {
                    collection.remove({ _id: mongo.ObjectId(decryptedId) }, function(err, docs) {
                        if (!err) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                        db.close();
                    });
                });
            });
        });
        return promise;
    },

    getAllArticle: function(whereStr) {
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.articlesTable, function(err, collection) {
                    collection.find(whereStr).sort({"publishTime":-1}).toArray(function(err, docs) {
                        db.close();
                        if (!err) {
                            docs.forEach(function(val) {
                                val._id = aesfn.aesEncrypt(val._id.toString());
                                val.publishTime = getTime(val.publishTime);
                            })
                            resolve(docs);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    getSomeArticle: function(whereStr) {
        const promise = new Promise(function(resolve, reject) {
            try{
                if(whereStr._id){
                    whereStr._id = mongo.ObjectId(aesfn.aesDecrypt(whereStr._id));
                } 
            }catch(e){
                reject(false);
                return false;
            }
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.articlesTable, function(err, collection) {
                    collection.find(whereStr).toArray(function(err, docs) {
                        if (!err) {
                            if(docs.length<1){
                                reject(false);
                                return false;
                            }
                            docs.forEach(function(val) {
                                val._id = aesfn.aesEncrypt(val._id.toString());
                                val.publishTime = getTime(val.publishTime);
                            });
                            db.close();
                            resolve(docs[0]);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    getAllDraft: function(whereStr) {
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.draftsTable, function(err, collection) {
                    collection.find(whereStr).toArray(function(err, docs) {
                        db.close();
                        if (!err) {
                            docs.forEach(function(val) {
                                val._id = aesfn.aesEncrypt(val._id.toString());
                            })
                            resolve(docs);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    getSomeDraft: function(whereStr) {
        const promise = new Promise(function(resolve, reject) {
            try{
                if(whereStr._id){
                    whereStr._id = mongo.ObjectId(aesfn.aesDecrypt(whereStr._id));
                } 
            }catch(e){
                reject(false);
                return false;
            }
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.draftsTable, function(err, collection) {
                    collection.find(whereStr).toArray(function(err, docs) {
                        if (!err) {
                            if(docs.length<1){
                                reject(false);
                                return false;
                            }
                            docs.forEach(function(val) {
                                val._id = aesfn.aesEncrypt(val._id.toString());
                            });
                            db.close();
                            resolve(docs[0]);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    updateArticle: function(data) {
        //id is a string just like '42314gh243214hb4'   
        const promise = new Promise(function(resolve, reject) {
            let decryptedId = aesfn.aesDecrypt(data._id);
            data.publishTime = new Date();
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.articlesTable, function(err, collection) {
                    collection.update({ '_id': mongo.ObjectId(decryptedId) }, { $set: { 'title': data.title, 'markdown': data.markdown, 'html': data.html,'tags': data.tags.split(',')} }, function(err, result) {
                        if (!err) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    checkUsernamePassword:function(data){
        data.userName = hmacCrypto(data.userName,config.adminKey);
        data.password = hmacCrypto(data.password,config.adminKey);
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.adminTable, function(err, collection) {
                    collection.find({userName:data.userName,password:data.password}).toArray(function(err, result) {
                        db.close();
                        if (!err&&result.length>0) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    checkSessionID:function(id){
        const promise = new Promise(function(resolve, reject) {
            if(id){
                MongoClient.connect(DB_CONN_STR, function(err, db) {
                    db.collection(config.adminTable, function(err, collection) {
                        collection.find({sessionID:id}).toArray(function(err, result) {
                            db.close();
                            if (!err&&result.length>0) {
                                resolve(true);
                            } else {
                                reject(false);
                            }
                        });
                    });
                });
            }else{
                reject(false);
            }
        });
        return promise;
    },

    updateSessionID:function(id){
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.adminTable, function(err, collection) {
                    collection.update({ 'key':'admin' }, { $set: { 'sessionID':id } }, function(err, result) {
                        db.close();
                        if (!err) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    setAboutme: function(data) {
        //id is a string just like '42314gh243214hb4'   
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.adminTable, function(err, collection) {
                    collection.update({ 'key': 'admin' }, { $set: { 'markdown': data.markdown, 'html': data.html} }, function(err, result) {
                        if (!err) {
                            resolve(true);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    getAboutme: function() {
        const promise = new Promise(function(resolve, reject) {
            MongoClient.connect(DB_CONN_STR, function(err, db) {
                db.collection(config.adminTable, function(err, collection) {
                    collection.find({'key':'admin'}).toArray(function(err, docs) {
                        if (!err) {
                            if(docs.length<1){
                                reject(false);
                                return false;
                            }
                            db.close();
                            resolve(docs[0]);
                        } else {
                            reject(false);
                        }
                    });
                });
            });
        });
        return promise;
    },

    changeUP:function(data){
        const promise = new Promise(function(resolve, reject) {
            if(data.username!==''&&data.password!==''){
                data.username = hmacCrypto(data.username,config.adminKey);
                data.password = hmacCrypto(data.password,config.adminKey);
                MongoClient.connect(DB_CONN_STR, function(err, db) {
                    db.collection(config.adminTable, function(err, collection) {
                        collection.update({ 'key':'admin' }, { $set: { 'userName':data.username,'password':data.password } }, function(err, result) {
                            db.close();
                            if (!err) {
                                resolve(true);
                            } else {
                                reject(false);
                            }
                        });
                    });
                });
            }else{
                reject(false);
            }
            
        });
        return promise;
    },
}

module.exports = articleOperate;
